min_caml_start まわりのコードを確認
C言語とのインターフェースとなるmin_caml_start まわりのソースを確認してみる。
PowerPC版ののemit.mlのコードが参考になりそう。
全体のソース
code:ml
let f oc (Prog(data, fundefs, e)) =
Format.eprintf "generating assembly...@.";
if data <> [] then
(Printf.fprintf oc "\t.data\n\t.literal8\n";
List.iter
(fun (Id.L(x), d) ->
Printf.fprintf oc "\t.align 3\n";
Printf.fprintf oc "%s:\t # %f\n" x d;
Printf.fprintf oc "\t.long\t%ld\n" (gethi d);
Printf.fprintf oc "\t.long\t%ld\n" (getlo d))
data);
Printf.fprintf oc "\t.text\n";
Printf.fprintf oc "\t.globl _min_caml_start\n";
Printf.fprintf oc "\t.align 2\n";
List.iter (fun fundef -> h oc fundef) fundefs;
Printf.fprintf oc "_min_caml_start: # main entry point\n";
Printf.fprintf oc "\tmflr\tr0\n";
Printf.fprintf oc "\tstmw\tr30, -8(r1)\n";
Printf.fprintf oc "\tstw\tr0, 8(r1)\n";
Printf.fprintf oc "\tstwu\tr1, -96(r1)\n";
Printf.fprintf oc "#\tmain program starts\n";
stackset := S.empty;
stackmap := [];
g oc (NonTail("_R_0"), e);
Printf.fprintf oc "#\tmain program ends\n";
(* Printf.fprintf oc "\tmr\tr3, %s\n" regs.(0); *)
Printf.fprintf oc "\tlwz\tr1, 0(r1)\n";
Printf.fprintf oc "\tlwz\tr0, 8(r1)\n";
Printf.fprintf oc "\tmtlr\tr0\n";
Printf.fprintf oc "\tlmw\tr30, -8(r1)\n";
Printf.fprintf oc "\tblr\n"
mainから呼び出し ~ プログラム開始直前
code:ml
Printf.fprintf oc "_min_caml_start: # main entry point\n";
Printf.fprintf oc "\tmflr\tr0\n";
Printf.fprintf oc "\tstmw\tr30, -8(r1)\n";
Printf.fprintf oc "\tstw\tr0, 8(r1)\n";
Printf.fprintf oc "\tstwu\tr1, -96(r1)\n";
Printf.fprintf oc "#\tmain program starts\n";
mflr r0
r0 へリンクレジスタの値をmove
stmw r30, -8(r1)
stw r0, 8(r1)
stwu r1, -96(41)
プログラム終了 〜 main へ戻る直前
code:ml
Printf.fprintf oc "#\tmain program ends\n";
(* Printf.fprintf oc "\tmr\tr3, %s\n" regs.(0); *)
Printf.fprintf oc "\tlwz\tr1, 0(r1)\n";
Printf.fprintf oc "\tlwz\tr0, 8(r1)\n";
Printf.fprintf oc "\tmtlr\tr0\n";
Printf.fprintf oc "\tlmw\tr30, -8(r1)\n";
Printf.fprintf oc "\tblr\n"
lwz r1, 0(r1)
lwz r0, 8(r1)
mtlr r0
r0に格納された値をリンクレジスタへmove
lmw r30, -8(r1)
blr
mainへ戻る